from django.contrib.auth.models import Permission, Group

from rest_framework import viewsets, mixins, response, status
from rest_framework.generics import get_object_or_404

from permissions.serializers import PermissionSerializer, MenuSerializer
# from permissions.filter import PermissionFilter
from permissions.models import Menu
from permissions.common import get_menu_tree


class PermissionViewset(viewsets.ReadOnlyModelViewSet):
    """
    权限只读视图

    list: 列出所有权限
    """
    queryset = Permission.objects.all().order_by('content_type__id')
    serializer_class = PermissionSerializer
    pagination_class = None  # 权限数据不分页


# class GroupPermissionViewset(viewsets.ReadOnlyModelViewSet, mixins.UpdateModelMixin, mixins.DestroyModelMixin):
#     """
#     用户组权限视图集
#     update: 给用户组增加权限，需要传递权限id
#     destroy: 删除用户组下的权限，需要传递权限id
#     """
#     queryset = Permission.objects.all()
#     serializer_class = PermissionSerializer
#     filter_class = PermissionFilter
#     filter_fields = ('name', )
#
#     @staticmethod
#     def get_permission_obj(pid):
#         try:
#             return Permission.objects.get(pk=pid)
#         except Permission.DoesNotExist:
#             return None
#
#     def get_object(self):
#         """
#         重写方法，只改了queryset变量
#         """
#         queryset = Group.objects.all()
#         lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
#
#         assert lookup_url_kwarg in self.kwargs, (
#                 'Expected view %s to be called with a URL keyword argument '
#                 'named "%s". Fix your URL conf, or set the `.lookup_field` '
#                 'attribute on the view correctly.' %
#                 (self.__class__.__name__, lookup_url_kwarg)
#         )
#
#         filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
#         obj = get_object_or_404(queryset, **filter_kwargs)
#
#         # May raise a permission denied
#         self.check_object_permissions(self.request, obj)
#         return obj
#
#     @staticmethod
#     def process_permission(group_permission_queryset, data):
#         """
#         默认权限状态为False，若该组有权限，则将权限标记为True
#         """
#         for record in data:
#             try:
#                 group_permission_queryset.get(pk=record.get("id", None))
#                 record["status"] = True
#             except:
#                 pass
#         return data
#
#     def get_group_permissions(self):
#         groupobj = self.get_object()
#         queryset = groupobj.permissions.all()
#         queryset = self.filter_queryset(queryset)
#         page = self.paginate_queryset(queryset)
#         if page is not None:
#             serializer = self.get_serializer(page, many=True)
#             return self.get_paginated_response(serializer.data)
#
#         serializer = self.get_serializer(queryset, many=True)
#         return response.Response(serializer.data)
#
#     def get_modify_permissions(self):
#         """
#         返回用户已有的权限列表，并标记状态为True
#         """
#         groupobj = self.get_object()
#         group_permission_queryset = groupobj.permissions.all()
#         queryset = Permission.objects.all()
#         queryset = self.filter_queryset(queryset)
#         page = self.paginate_queryset(queryset)
#         if page is not None:
#             serializer = self.get_serializer(page, many=True)
#             return self.get_paginated_response(self.process_permission(group_permission_queryset, serializer.data))
#
#         serializer = self.get_serializer(queryset, many=True)
#         return response.Response(self.process_permission(group_permission_queryset, serializer.data))
#
#     def retrieve(self, request, *args, **kwargs):
#         modify = request.GET.get("modify", None)
#         if modify is not None:
#             return self.get_modify_permissions()
#         else:
#             return self.get_group_permissions()
#
#     def update(self, request, *args, **kwargs):
#         result = {"status": 0}
#         groupobj = self.get_object()
#         permission_obj = self.get_permission_obj(request.data.get("pid", ""))
#         if permission_obj is None:
#             result["status"] = 1
#             result["errmsg"] = "permission 不存在"
#         else:
#             groupobj.permissions.add(permission_obj)
#         return response.Response(result, status=status.HTTP_200_OK)
#
#     def destroy(self, request, *args, **kwargs):
#         result = {"status": 0}
#         groupobj = self.get_object()
#         permission_obj = self.get_permission_obj(request.data.get("pid", ""))
#         if permission_obj is None:
#             result["status"] = 1
#             result["errmsg"] = "permission 不存在"
#         else:
#             groupobj.permissions.remove(permission_obj)
#         return response.Response(result, status=status.HTTP_200_OK)


class MenuViewSet(viewsets.ModelViewSet):
    """
    前端左侧菜单
    retrieve: 返回指定菜单信息
    list: 返回菜单列表
    update: 更新菜单信息
    destroy: 删除菜单记录
    create: 创建菜单资源
    partial_update: 更新部分字段
    """
    queryset = Menu.objects.all()
    serializer_class = MenuSerializer


class GroupMenuViewset(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    用户组菜单权限
    update: 给指定用户组增加菜单，需要传递参数菜单id
    destroy: 删除指定组下的菜单，需要传递参数菜单id
    """
    queryset = Menu.objects.all()
    serializer_class = MenuSerializer

    def process_menu(self, group_permission_queryset, data):
        for record in data:  # 若有权限标记为True
            try:
                group_permission_queryset.get(pk=record.get("id", None))
                record["status"] = True
            except:
                pass
        return data

    def get_group_menus(self):
        groupobj = self.get_object()
        queryset = groupobj.menu_set.all()
        data = get_menu_tree(queryset)
        return response.Response(data)

    def get_modify_menus(self):
        groupobj = self.get_object()
        group_menu_queryset = groupobj.menu_set.all()
        queryset = Menu.objects.all()
        result = {}
        result["data"] = get_menu_tree(queryset, group_menu_queryset)
        result["permissions"] = [obj.id for obj in group_menu_queryset]
        return response.Response(result)

    def retrieve(self, request, *args, **kwargs):
        modify = request.GET.get("modify", None)
        if modify is not None:
            return self.get_modify_menus()
        else:
            return self.get_group_menus()

    def get_object(self):
        """
        重写get_object，修改了queryset
        """
        queryset = Group.objects.all()
        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
        assert lookup_url_kwarg in self.kwargs, (
            'Expected view %s to be called with a URL keyword argument '
            'named "%s". Fix your URL conf, or set the `.lookup_field` '
            'attribute on the view correctly.' %
            (self.__class__.__name__, lookup_url_kwarg)
        )

        filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
        obj = get_object_or_404(queryset, **filter_kwargs)

        self.check_object_permissions(self.request, obj)
        return obj

    def update(self, request, *args, **kwargs):
        result = {"status": 0}
        groupobj = self.get_object()
        menu_objects = Menu.objects.filter(pk__in=request.data.get("mid"))
        groupobj.menu_set = menu_objects
        return response.Response(result, status=status.HTTP_200_OK)
